package com.chuanyun.wechatcheckin.service;

import com.chuanyun.wechatcheckin.config.WechatConfig;
import com.chuanyun.wechatcheckin.model.wechat.WechatTokenResponse;
import com.chuanyun.wechatcheckin.model.wechat.WechatUserListResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 企业微信API服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WechatApiService {
    
    private final WechatConfig wechatConfig;
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 获取通讯录访问令牌（使用通讯录同步Secret）
     */
    public String getAccessToken() throws Exception {
        String url = wechatConfig.getApi().getBaseUrl() + wechatConfig.getApi().getTokenUrl() +
                "?corpid=" + wechatConfig.getCorpId() +
                "&corpsecret=" + wechatConfig.getContactSecret();
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            
            return httpClient.execute(httpGet, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                
                WechatTokenResponse tokenResponse = objectMapper.readValue(responseBody, WechatTokenResponse.class);
                
                if (tokenResponse.isSuccess()) {
                    return tokenResponse.getAccessToken();
                } else {
                    log.error("获取企业微信通讯录访问令牌失败: {}", tokenResponse.getErrMsg());
                    throw new RuntimeException("获取通讯录访问令牌失败: " + tokenResponse.getErrMsg());
                }
            });
        }
    }

    /**
     * 获取打卡应用访问令牌（使用打卡应用Secret）
     * @return 访问令牌 
     * @throws Exception
     */
    public String getCheckinAccessToken() throws Exception {
        String url = wechatConfig.getApi().getBaseUrl() + wechatConfig.getApi().getTokenUrl() +
                "?corpid=" + wechatConfig.getCorpId() +
                "&corpsecret=" + wechatConfig.getCheckinSecret();
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            
            return httpClient.execute(httpGet, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                
                WechatTokenResponse tokenResponse = objectMapper.readValue(responseBody, WechatTokenResponse.class);
                
                if (tokenResponse.isSuccess()) {
                    return tokenResponse.getAccessToken();
                } else {
                    log.error("获取企业微信打卡应用访问令牌失败: {}", tokenResponse.getErrMsg());
                    throw new RuntimeException("获取访问令牌失败: " + tokenResponse.getErrMsg());
                }
            });
        }
    }   
    
    /**
     * 获取所有用户ID列表
     * 从企业微信获取用户数据，只提取userid字段
     */
    public List<String> getAllUserIds() throws Exception {
        String accessToken = getAccessToken();
        Set<String> userIdSet = new HashSet<>(); // 使用Set进行高效去重
        String cursor = null;
        int pageCount = 0;
        
        log.info("开始从企业微信获取用户ID列表");
        
        do {
            pageCount++;
            WechatUserListResponse response = getUserList(accessToken, cursor);
            
            if (response.getDeptUser() != null && !response.getDeptUser().isEmpty()) {
                // 提取当前页的所有userid
                List<String> currentPageUserIds = extractUserIdsFromResponse(response);
                
                // 添加到Set中自动去重
                int beforeSize = userIdSet.size();
                userIdSet.addAll(currentPageUserIds);
                int addedCount = userIdSet.size() - beforeSize;
                
                log.info("第{}页: 获取{}个用户，新增{}个", pageCount, currentPageUserIds.size(), addedCount);
            }
            
            cursor = response.getNextCursor();
            
        } while (cursor != null && !cursor.isEmpty());
        
        List<String> result = new ArrayList<>(userIdSet);
        log.info("企业微信用户ID获取完成: 共{}页，总用户数: {}", pageCount, result.size());
        return result;
    }
    
    /**
     * 从企业微信响应中提取用户ID列表
     * @param response 企业微信API响应
     * @return 用户ID列表
     */
    private List<String> extractUserIdsFromResponse(WechatUserListResponse response) {
        if (response == null || response.getDeptUser() == null) {
            return new ArrayList<>();
        }
        
        return response.getDeptUser().stream()
                .map(WechatUserListResponse.DeptUser::getUserId)
                .filter(userId -> userId != null && !userId.trim().isEmpty())
                .distinct()
                .toList();
    }
    
    /**
     * 获取用户列表（分页）
     */
    private WechatUserListResponse getUserList(String accessToken, String cursor) throws Exception {
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(wechatConfig.getApi().getBaseUrl())
                .append(wechatConfig.getApi().getUserListUrl())
                .append("?access_token=").append(accessToken)
                .append("&limit=1000");
        
        if (cursor != null && !cursor.isEmpty()) {
            urlBuilder.append("&cursor=").append(cursor);
        }
        
        String url = urlBuilder.toString();
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            
            ClassicHttpResponse response = httpClient.execute(httpGet);
            String responseBody = EntityUtils.toString(response.getEntity());
            
            WechatUserListResponse userListResponse = objectMapper.readValue(responseBody, WechatUserListResponse.class);
            
            if (!userListResponse.isSuccess()) {
                log.error("获取企业微信用户列表失败: {}", userListResponse.getErrMsg());
                throw new RuntimeException(String.format("获取用户列表失败: %s", userListResponse.getErrMsg()));
            }
            
            return userListResponse;
        }
    }
}